﻿#ifndef PICKARM_H
#define PICKARM_H

#include "systemCore/worker.h"
#include "AxisModule/singleaxis.h"
#include "AxisModule/xyzmodule.h"
#include "CompositeElement/sccylinder.h"
#include "CompositeElement/scvacuum.h"
#include "CompositeElement/twoaxisplanner.h"
#include "Tray/trayconfig.h"
#include "TwoDimCali/twodimensioncalibration.h"
#include "VisionManager/visionmanager.h"
#include "namedefinition.h"
#include "systemCore/worker.h"
#include "pickarmconfig.h"
#include "Tray/lenstraymap.h"
#include "Tray/sensortraymap.h"

class PickArm : public Worker
{
    Q_OBJECT
public:
    PickArm(TrayConfig *sensorTrayConfig, TrayConfig *lensTrayConfig,TrayConfig *rejectTrayConfig,
            SensorTrayMap *sensorTrayMap,   LensTrayMap *lensTrayMap, SensorTrayMap *rejectTrayMap);
    ~PickArm() override;
    PickArmConfig *getPaConfig()const
    {
        return paConfig;
    }

    // Worker interface
protected:
    virtual void initEventHandle() override;
    virtual void startEventHandle(const WorkerEvent &event) override;
    virtual void stopEventHandle() override {}
    virtual void allWorkerStopped() override;
    virtual void purgeEventHandle() override;
    virtual void resetEventHandle() override;
    virtual void homeWorker(bool moveToReadyPosAfterHome) override;

    //自动运行逻辑
public slots:
    void stratAuto();
    void loadMaterialFunction(QString type);
    void pickLensFunction();
    void pickSenorFunction();
    void placeLensToLUT();
    void placeSensorToSUT();
    void pickOkProduct();
    void placeOkProductFunction();
    void pickNGProductFunction();
    void placeNGProductFunction();
    void pickNgLens();
    void placeNgLensFunction();
    void pickNgSensor(bool isNGProduct);
    void placeNgSensorFunction();
    void moveTrayLoaderToExchangePos();
    void placeMaterial(QString type);
    void postAAHeadRun(QString type);
    void exchangeTray(QString trayType);

    //手动调试操作
public slots:
    void calibratePickerToDownLookCameraOffset(bool isSensorPicker);
    void moveToPickCalibrateGlass(bool isSensorPicker);
    void moveToPickerPrPos(bool isSensorPicker);

    void moveToPickLens(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void moveToPickSensor(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void moveToPlaceLensToLut();
    void moveToPlaceSensorToSut();

    void moveToLensPrPos(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void moveToSensorPrPos(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void moveToRejectSensorPos(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);

    void moveToGetRejectLens();
    void moveToGetRejectSensor();
    void moveToGetOKProduct();
    void moveToPlaceRejectLens(int rowIndexInside, int columnIndexInside, int unitRowIndex, int unitColumnIndex);
    void moveToPlaceRejectSensor(int rowIndexInside, int columnIndexInside, int unitRowIndex, int unitColumnIndex);
    void moveToPlaceOKProduct(int rowIndexInside, int columnIndexInside, int unitRowIndex, int unitColumnIndex);

    void pickGlassWithOffset(bool isSensorPicker);
    void placeCalibGlass(bool isSensorPicker);
    void placeBackMaterial(bool isSenserPicker);

    //inside function
public slots:
    void pickMaterial(bool isSensorPicker);

    bool pickeLens(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    bool pickSensor(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void placeOkProduct(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void placeNgLens(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);
    void placeNgSensor(int rowIndexInside, int columnIndexInside, int unitRowIndex = 1, int unitColumnIndex = 1);

private:
    void moveToPickCalibrateGlassPos(bool isSensorPicker);

    void pickCalibGlass(bool isSensorPicker);

    void moveToPADownlookPrPos(bool isSensorPicker);
    void moveToStanbyPos();
    void moveUpAllZ();

    PrOffset getPickerCaliGlassPrOffset(bool isSensorPicker);
    PrOffset getCaliGlassPrOffset();
    PrOffset getTrayUpLookCameraOffset(bool isSensorTray);
    PrOffset getRejectTrayUpLookCameraOffset();

    void setLensState(QPoint indexs, LensTrayMaterialData::MaterialState state);
    void setSensorState(QPoint indexs, SensorTrayMaterialData::MaterialState state);
    void setRejectState(QPoint indexs, SensorTrayMaterialData::MaterialState state);

    void lensTrayMoveNext();
    void sensorTrayMoveNext();
    void placeProducttMoveNext();

    void pickMaterialFailedHandle(bool isSensorPicker);
private:
    TrayConfig *sensorTrayConfig;
    TrayConfig *lensTrayConfig;
    TrayConfig *rejectTrayConfig;
    LensTrayMap *lensTrayMap;
    SensorTrayMap *sensorTrayMap;
    SensorTrayMap *rejectTrayMap;

    SingleAxis *PickerZ1;
    SingleAxis *PickerZ2;
    SingleAxis *PickerT1;
    SingleAxis *PickerT2;
    SingleAxis *trayLoaderX;
    SingleAxis *pickerArmY;
    SCAxis *pickerZ1Motor;
    SCAxis *pickerZ2Motor;

    XYModule *PickerXYmodule;
    XYZModule *SUTxyz;

    PickArmConfig *paConfig;
    ConfigFile *paConfigFile;

    VisionLocation *pickerCaliGlassLocation;
    VisionLocation *sensorTrayDownLookLocation;
    VisionLocation *lensTrayDownLookLocation;
    VisionLocation *rejectTrayDownLookLocation;

    SCVacuum *lensPickerVacuum;
    SCVacuum *sensorPickerVacuum;
    SCVacuum *ngSensorPickerVacuum;
    SCVacuum *sutVacuum;
    SCVacuum *lutVacuum;
    SCVacuum *RejectLVCM;

    SCCylinder *ngSensorPickerCylinder;
    SCCylinder *sutCylinder;

    bool isPaStopped = false;
    // to do debug
    bool finishPlanPlace = false;
    bool finishProduct = false;
};

class  MaterialPrErr : public SilicolError
{
public:
    MaterialPrErr()
        :SilicolError(WorkerName::PickArm,
                      QObject::tr("Material excute Pr failed!\r\n Option explantion:\r\nRetry: redo Pr again."
                                  "\r\nNext: move to pick next material.\r\nAbort: System abort."))
    {
        appendErrorHandlingOption(Retry_);
        appendErrorHandlingOption(ErrorHandlingOption::Next_);
        appendErrorHandlingOption(Abort_);
    }

protected:
    virtual void implemented() override {}
};

class PickMaterialErr : public SilicolError
{
public:
    PickMaterialErr()
        : SilicolError (WorkerName::PickArm,
                        QObject::tr("pick material failed!\r\n Option explantion:\r\nRetry: pick again."
                                    "\r\nNext: move to pick next material.\r\nAbort: System abort."))
    {
        appendErrorHandlingOption(Retry_);
        appendErrorHandlingOption(ErrorHandlingOption::Next_);
        appendErrorHandlingOption(Abort_);
    }
protected:
    virtual void implemented() override {}
};

class PlaceSensorToSUTErr : public SilicolError
{
public:
    PlaceSensorToSUTErr() : SilicolError(WorkerName::PickArm,
                                 QObject::tr("SUT Cylinder in Clamp, would you like to extend it?  \r\nOption explantion: \r\n"
                                             "Extend: extend gripper. \r\nAbort: System abort."))
    {
        appendErrorHandlingOption(ErrorHandlingOption::Extend_);
        appendErrorHandlingOption(Abort_);
    }
protected:
    virtual void implemented() override {}
};

class NuzzleHasMaterial : public SilicolError{
public:
    NuzzleHasMaterial() : SilicolError(WorkerName::PickArm,
                                 QObject::tr("Nuzzle has material please check and handle it than continual. \r\nOption explantion: \r\n"
                                             "Continual: make sure finish handle than continual . \r\nAbort: System abort."))
    {
        appendErrorHandlingOption(ErrorHandlingOption::Continual_);
        appendErrorHandlingOption(Abort_);
    }
protected:
    virtual void implemented() override {}
};

#endif // PICKARM_H
